﻿/** 
 * Copyright 2010 NUMKIT.COM (contact: opensource@numkit.com)
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 * 
 * @author 陈超
 * @version 1.0
 */
import flash.external.ExternalInterface;
class Road{
	static private var textFormat:TextFormat;
	static private var defaultLink:String;
	static private var asyncMode:Boolean=false;
	static private var tipTF:TextField;
	static private var aColor:Array;
	private var aX:Array;
	private var aY:Array;
	private var aFontPos:Array;
	private var id:Number;
	private var type:Number=0;
	private var name:String="";
	private var link:String="";
	private var highlight:Boolean=false;
	private var outStand:Boolean=false;
	private var roadWidth:Number=10;
	private var aField:Array;
	private var aTextSize:Array;
	private var scale:Number=1;
	private var outStandMC:MovieClip;
	private var graphicMC:MovieClip;
	private var textMC:MovieClip;
	public function Road(node:XMLNode){
		if(textFormat==undefined){
			textFormat=new TextFormat();
			textFormat.size=12;
		}
		if(aColor==undefined){
			aColor=new Array();
			aColor.push(0xC4C2C4);
			aColor.push(0xF1BE23);
			aColor.push(0xFFD700);
			aColor.push(0x78C878);
			aColor.push(0xDAA0AE);
		}
		if (node.nodeName!="RD") {
			throw new Error("Not A Road Node!");
		}
		
		var idValue=parseInt(node.attributes["ID"]);
		if(!isNaN(idValue))
			id=idValue;

		// 设置RoadWidth,Point
		roadWidth= Number.MAX_VALUE;
		var aPoint:Array = new Array();
		for (var child:XMLNode = node.firstChild; child != null; child = child
				.nextSibling) {
			var nodeName:String = child.nodeName;
			if (nodeName=="Name") {
				this.name=child.firstChild.nodeValue;
			} else if (nodeName=="Link") {
				this.link=child.firstChild.nodeValue;
			} else if (nodeName=="Width") {
				this.roadWidth = parseInt(child.firstChild.nodeValue);
			} else if (nodeName=="P") {
				var x:Number = Number.MAX_VALUE;
				var y:Number = Number.MAX_VALUE;
				for (var pc:XMLNode = child.firstChild; pc != null; pc = pc
						.nextSibling) {
					if (pc.nodeName=="X")
						x = parseInt(pc.firstChild.nodeValue);
					else if (pc.nodeName=="Y")
						y = parseInt(pc.firstChild.nodeValue);
				}
				if (x == Number.MAX_VALUE || y == Number.MAX_VALUE) {
					throw new Error("Road Node Point Err!");
				}
				aPoint.push(new Point(x, y));
			}
		}
		if (roadWidth == Number.MAX_VALUE) {
			throw new Error("Road Node RoadWidth Not Set!");
		}
		aX = new Array();
		aY = new Array();
		for (var i:Number = 0; i < aPoint.length; i++) {
			var p:Point = aPoint[i];
			aX[i] = p.x;
			aY[i] = p.y;
		}
		// 设置aFontPos
		aFontPos=new Array();
		if (getName().length > 0
				&& aX.length >= 2) {
			var aLength:Array = new Array();
			var length:Number = 0;
			for (var i:Number = 0; i < aX.length - 1; i++) {
				aLength[i] = Math.sqrt(Math.pow(aX[i] - aX[i + 1], 2)
						+ Math.pow(aY[i] - aY[i + 1], 2));
				length += aLength[i];
			}
			var charCount:Number = getName().length;
			var step:Number = length / (charCount + 1);
			var target:Number = step;
			for (var i:Number = 0; i < charCount; i++) {
				var j:Number = 0;
				var walk:Number = 0;
				while (target > walk) {
					walk += aLength[j];
					j++;
				}
				var segBack:Number = aLength[j - 1] - (walk - target);
				var x:Number = segBack * (aX[j] - aX[j - 1]) / aLength[j - 1] + aX[j - 1];
				var y:Number = segBack * (aY[j] - aY[j - 1]) / aLength[j - 1] + aY[j - 1];
				aFontPos.push(new Point(x, y));
				target += step;
			}
		}
		//计算链接URL
		if(defaultLink!=undefined&&link==undefined){
			link=defaultLink;
			var pIndex:Number=defaultLink.indexOf("[Road]");
			if(pIndex!=-1){
				var aSplit=link.split("[Road]");
				link="";
				for(var j:Number=0;j<aSplit.length-1;j++){
					link+=aSplit[j]+name;
				}
				link+=aSplit[aSplit.length-1];
			}
			var iIndex:Number=defaultLink.indexOf("[ID]");
			if(iIndex!=-1){
				var aSplit=link.split("[ID]");
				link="";
				for(var j:Number=0;j<aSplit.length-1;j++){
					link+=aSplit[j]+id;
				}
				link+=aSplit[aSplit.length-1];
			}
		}
	}
	
	static public function setDefaultLink(theLink:String):Void{
		defaultLink=theLink;
	}
	
	static public function setTipTF(theTipTF:TextField):Void{
		tipTF=theTipTF;
	}
	
	public function drawGraphicPart(mc:MovieClip):Void{
		graphicMC=mc;
		if(aX==undefined||aY==undefined)
			return;
			
		if (roadWidth <= 5) {
			mc.lineStyle(roadWidth,aColor[0],100,true,"normal","square","miter", 0);
		} else if (roadWidth <= 10) {
			mc.lineStyle(roadWidth,aColor[1],100,true,"normal","square","miter", 0);
		} else if (roadWidth <= 15) {
			mc.lineStyle(roadWidth,aColor[2],100,true,"normal","square","miter", 0);
		} else if (roadWidth <= 20) {
			mc.lineStyle(roadWidth,aColor[3],100,true,"normal","square","miter", 0);
		} else {
			mc.lineStyle(roadWidth,aColor[4],100,true,"normal","square","miter", 0);
		}
		mc.moveTo(aX[0],aY[0]);
		for(var i:Number=0;i<aX.length-1;i++){
			mc.lineTo(aX[i+1],aY[i+1]);
		}
		//添加事件处理
		mc.tipTF=tipTF;
		var highlightMC:MovieClip;
		mc.highlightMC=highlightMC;
		mc.roadWidth=roadWidth;
		mc.aX=aX;
		mc.aY=aY;
		var fontSize:Object=textFormat.getTextExtent(name);
		mc.fontSize=fontSize;
		var road:Road=this;
		mc.road=road;
		mc.onRollOver = function():Void{
			var name:String=road.getName();
			if(name!=undefined&&name!=""){
				tipTF.text=name;
				tipTF._width=fontSize.textFieldWidth;
				tipTF._visible=true;
			}
			if(highlightMC!=undefined)
			{
				highlightMC.removeMovieClip();
				highlightMC=undefined;
			}
			highlightMC=this._parent.createEmptyMovieClip("highlightMC", this._parent.getNextHighestDepth());
			highlightMC.lineStyle(roadWidth,0xADEAFE,100);
			highlightMC.moveTo(aX[0],aY[0]);
			for(var i:Number=0;i<aX.length-1;i++){
				highlightMC.lineTo(aX[i+1],aY[i+1]);
			}
		};
		mc.onRollOut = function():Void{
			tipTF.text="";
			tipTF._visible=false;
			if(highlightMC!=undefined)
			{
				highlightMC.removeMovieClip();
				highlightMC=undefined;
			}
		};
		mc.onRelease = function():Void{
			if(Road.isAsyncMode()){
				var id:Number=road.getID();
				var name:String=road.getName();
				ExternalInterface.call("onRoadClicked",name,id);
			}
			else{
				var link:String=road.getLink();
				if(link!=undefined&&link!=""){
					getUrl(link,"_blank");
				}
			}
		};
	}
	public function drawTextPart(mc:MovieClip):Void{
		textMC=mc;
		aField=new Array();
		aTextSize=new Array();
		if (aFontPos!=undefined&&aFontPos.length > 0) {
			var firstPos:Point = aFontPos[0];
			var lastPos:Point = aFontPos[aFontPos.length - 1];
			if (lastPos.y - firstPos.y > firstPos.x - lastPos.x) {
				for (var i:Number = 0; i < aFontPos.length; i++) {
					var p:Point = aFontPos[i];
					var c:String = name.charAt(i);
					var textSize:Object=textFormat.getTextExtent(c);
					var charField=mc.createTextField("Char"+i,mc.getNextHighestDepth(), 
						(p.x - textSize.textFieldWidth / 2), 
						(p.y - textSize.textFieldHeight / 2),
						textSize.textFieldWidth,
						textSize.textFieldHeight);
					charField.text=c;
					charField.selectable=false;
					charField.setTextFormat(textFormat);
					aTextSize[i]=textSize;
					aField[i]=charField;
				}
			} else {
				for (var i:Number = aFontPos.length - 1; i >= 0; i--) {
					var p:Point = aFontPos[i];
					var c:String = getName().charAt(aFontPos.length - 1 - i);
					var textSize:Object=textFormat.getTextExtent(c);
					var charField=mc.createTextField("Char"+i,mc.getNextHighestDepth(), 
						(p.x - textSize.textFieldWidth / 2 ), 
						(p.y - textSize.textFieldHeight / 2 ),
						textSize.textFieldWidth,
						textSize.textFieldHeight);
					charField.text=c;
					charField.selectable=false;
					charField.setTextFormat(textFormat);
					aTextSize[i]=textSize;
					aField[i]=charField;
				}
			}
		}
		if(getName().length* 14 > getRoadLength()*scale|| 8>getRoadWidth()*scale){
			for(var i:Number=0;i<aField.length;i++){
				aField[i]._visible=false;
			}
		}
	}
	public function setScale(scale:Number):Void{
		if(this.scale!=scale){
			for(var i:Number=0;i<aFontPos.length;i++){
				var p:Point = aFontPos[i];
				aField[i]._x=p.x*scale - aTextSize[i].textFieldWidth / 2;
				aField[i]._y=p.y*scale  - aTextSize[i].textFieldHeight / 2;
			}
			this.scale=scale;
			if(getName().length* 14 > getRoadLength()*scale|| 5>getRoadWidth()*scale){
				for(var i:Number=0;i<aField.length;i++){
					aField[i]._visible=false;
				}
			}else{
				for(var i:Number=0;i<aField.length;i++){
					aField[i]._visible=true;
				}
			}
		}
	}
	public function getScale():Number{
		return scale;
	}
	public function setHighlighted(highlighted:Boolean):Void{
		this.highlight=highlighted;
	}
	public function isHighlighted():Boolean{
		return highlight;
	}
	public function getLink():String{
		return link;
	}
	public function getRoadWidth(){
		return this.roadWidth;
	}
	public function getRoadLength(){
		if (aX == undefined || aY == undefined)
			return 0;
		var length:Number = 0;
		for (var i:Number = 0; i < aX.length - 1; i++) {
			length += Math.sqrt(Math.pow(aX[i] - aX[i + 1], 2)
					+ Math.pow(aY[i] - aY[i + 1], 2));
		}
		return length;
	}
	public function getName():String{
		return name;
	}
	public function getCenterX():Number{
		var maxX = Number.MIN_VALUE;
		var minX = Number.MAX_VALUE;
		for (var i:Number = 0; i < aX.length; i++) {
			if (aX[i] > maxX)
				maxX = aX[i];
			if (aX[i] < minX)
				minX = aX[i];
		}
		return (minX+maxX)/2;
	}
	public function getCenterY():Number{
		var maxY = Number.MIN_VALUE;
		var minY = Number.MAX_VALUE;
		for (var i:Number = 0; i < aY.length; i++) {
			if (aY[i] > maxY)
				maxY = aY[i];
			if (aY[i] < minY)
				minY = aY[i];
		}
		return (minY+maxY)/2;
	}
	
	static public function isAsyncMode():Boolean{
		return asyncMode;
	}
	
	static public function setAsyncMode(async:Boolean):Void{
		asyncMode=async;
	}
	
	public function getID():Number{
		return id;
	}
	
	public function setOutStand(outStand:Boolean):Void{
		if(this.outStand!=outStand){
			if(outStand){
				outStandMC=graphicMC._parent.createEmptyMovieClip("outStandMC", graphicMC._parent.getNextHighestDepth());
				outStandMC.lineStyle(roadWidth,0x16e316,100);
				outStandMC.moveTo(aX[0],aY[0]);
				for(var i:Number=0;i<aX.length-1;i++){
					outStandMC.lineTo(aX[i+1],aY[i+1]);
				}
			}else{
				outStandMC.removeMovieClip();
			}
			this.outStand=outStand;
		}
	}
	
	public function isOutStand():Boolean{
		return outStand;
	}
	
}